﻿///////////////////////////////////////////////////////////////////////////////////////////////
// System.Text.Parsing - © 2011 Sebastien Pellizzari
// Released under the MIT License (http://www.opensource.org/licenses/mit-license.php)
///////////////////////////////////////////////////////////////////////////////////////////////
using System.Collections.Generic;
using System.Collections;

namespace System.Text.Parsing
{
    /// <summary>Represents a collection of code block definitions.</summary>
    public sealed class GrammarCodeBlockCollection : IEnumerable<GrammarCodeBlock>
    {
        private readonly Dictionary<string, GrammarCodeBlock> _elements;

        //-----------------------------------------------------------------------
        //     Properties
        //-----------------------------------------------------------------------

        /// <summary>Gets the number of elements in the collection.</summary>
        public int Count { get { return _elements.Count; } }

        /// <summary>Gets the code block with specified name, or a null reference if not found.</summary>
        /// <param name="name">The code block name.</param>
        public GrammarCodeBlock this[string name]
        {
            get
            {
                GrammarCodeBlock codeBlock;
                if (_elements.TryGetValue(name, out codeBlock)) return codeBlock;
                return null;
            }
        }

        //-----------------------------------------------------------------------
        //     Constructors
        //-----------------------------------------------------------------------

        /// <summary>Initializes an instance of the <see cref="GrammarCodeBlockCollection"/> class.</summary>
        public GrammarCodeBlockCollection() { _elements = new Dictionary<string, GrammarCodeBlock>(); }

        //-----------------------------------------------------------------------
        //     Methods
        //-----------------------------------------------------------------------

        /// <summary>Determines whether the collection contains a code block with specified name.</summary>
        public bool Contains(string name) { return _elements.ContainsKey(name); }

        /// <summary>Tries to get the code block with specified name.</summary>
        /// <param name="name">The name of desired code block.</param>
        /// <param name="codeBlock">The resulting code block.</param>
        /// <returns>true if found; false otherwise.</returns>
        public bool TryGetValue(string name, out GrammarCodeBlock codeBlock)
        {
            return _elements.TryGetValue(name, out codeBlock);
        }

        /// <summary>Adds an element to the collection.</summary>
        /// <param name="codeBlock">The code block to add.</param>
        public void Add(GrammarCodeBlock codeBlock)
        {
            if (codeBlock == null) throw new ArgumentNullException("codeBlock");
            _elements[codeBlock.Name.Text] = codeBlock;
        }

        /// <summary>Removes the code block with specified name from the collection.</summary>
        /// <param name="name">The name of the code block to remove.</param>
        /// <returns>true if succeeded; false otherwise.</returns>
        public bool Remove(string name) { return _elements.Remove(name); }

        /// <summary>Returns an object that iterates through the collection.</summary>
        /// <returns>An object that implements the <see cref="IEnumerator{GrammarCodeBlock}"/> interface.</returns>
        public IEnumerator<GrammarCodeBlock> GetEnumerator() { return _elements.Values.GetEnumerator(); }

        //-----------------------------------------------------------------------
        //     Non Public
        //-----------------------------------------------------------------------

        // GetEnumerator method.
        IEnumerator IEnumerable.GetEnumerator() { return _elements.Values.GetEnumerator(); }
    }
}
